﻿using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;

namespace TinyAsset.Editor
{
    [CreateAssetMenu()]
    public class BuildHistoryRegistry : ScriptableObject
    {
        [Serializable]
        public class HistoryRecord
        {
            public BuildTarget buildTarget = BuildTarget.NoTarget;

            public List<string> history = new List<string>();
        }

        [SerializeField]
        List<HistoryRecord> m_AppBuildVersions = new List<HistoryRecord>();

        [SerializeField]
        List<HistoryRecord> m_ResBuildVersions = new List<HistoryRecord>();

        const string kDefaultVersionStr = "1.0.0.0";

        static readonly int[] kMaxVersionBit = { 8, 8, 16, 0 };

        public void SetCurrentAppVersion(BuildTarget target, Version version)
        {
            HistoryRecord history = GetCurrentAppHistory(target);
            if (history == null)
            {
                history = new HistoryRecord() { buildTarget = target };
                m_AppBuildVersions.Add(history);
            }
            history.history.Add(version.ToString());
        }

        public void SetCurrentResVersion(BuildTarget target, Version version)
        {
            HistoryRecord history = GetCurrentResHistory(target);
            if (history == null)
            {
                history = new HistoryRecord() { buildTarget = target };
                m_ResBuildVersions.Add(history);
            }
            history.history.Add(version.ToString());
        }

        public Version GetCurrentAppVersion(BuildTarget target)
        {
            HistoryRecord history = GetCurrentAppHistory(target);
            if (history == null)
                return null;
            return new Version(history.history[history.history.Count - 1]);
        }

        public Version GetNextAppVerion(BuildTarget target)
        {
            Version current = GetCurrentAppVersion(target);
            return ComputeNext(current);
        }

        public Version GetCurrentResVersion(BuildTarget target)
        {
            HistoryRecord history = GetCurrentResHistory(target);
            if (history == null)
                return null;
            return new Version(history.history[history.history.Count - 1]);
        }

        public Version GetNextResVersion(BuildTarget target)
        {
            Version current = GetCurrentResVersion(target);
            return ComputeNext(current);
        }

        public static int GetVersionNumber(Version version)
        {
            int num = 0;
            int offset = 0;
            int[] arr = new int[] { version.Major,version.Minor,version.Build,version.Revision };
            for (int i = 0; i < arr.Length; i++)
            {
                num = num | (arr[i] << (32 - kMaxVersionBit[i])) >> offset;
                offset = offset + kMaxVersionBit[i];
            }
            return num;
        }

        HistoryRecord GetCurrentAppHistory(BuildTarget target)
        {
            return m_AppBuildVersions.Find(h => h.buildTarget == target);
        }

        HistoryRecord GetCurrentResHistory(BuildTarget target)
        {
            return m_ResBuildVersions.Find(h => h.buildTarget == target);
        }

        Version ComputeNext(Version version)
        {
            if (version == null)
                return new Version(kDefaultVersionStr);

            int[] arr = new int[] { version.Major,version.Minor,version.Build,version.Revision };
            for (int i = arr.Length - 1; i >= 0; i--)
            {
                arr[i] = arr[i] + 1;
                if (kMaxVersionBit[i] > 0 && arr[i] < (1 << kMaxVersionBit[i]))
                    break;
                arr[i] = 0;
            }
            return new Version(arr[0],arr[1],arr[2],arr[3]);
        }
    }
}